//
//  Dimensions.swift
//  DesignKit
//
//  Created by x on 2024/2/29.
//

import Foundation

/*
 •    100：最细（Thin）。
 •    200：细（Extra Light）。
 •    300：略细（Light）。
 •    400：正常（Normal）。
 •    500：稍粗（Medium）。
 •    600：半粗（Semi Bold）。
 •    700：粗（Bold）。
 •    800：更粗（Extra Bold）。
 •    900：最粗（Black）。
 */
/*
 •  Text Style         用途       默认大小     示例用途
 •  body          正文、段落文本     17pt      大部分普通文本内容
 • .headline      标题、重要信息     17pt      主要标题、突出文本
 • .subheadline   副标题、次要信息    15pt     描述性文本、次要标题
 • .largeTitle    大标题、主标题     34pt     界面顶部的大标题
 • .title1          主要标题        28pt     主要的一级标题
 • .title2          次要标题        22pt     次要标题
 • .title3          三级标题        20pt     三级标题
 • .caption1       图片说明、标签    12pt     小的说明文字
 • .caption2       细节说明、标签    11pt     更小的说明文字
 • .footnote       脚注、引用       13pt     用于脚注、注释
 • .callout       突出信息、强调    较大字体    强调信息
 
 
 */


extension UIFont: DesignWarapper { }

public extension Wrapper where Base: UIFont {
    static var navigationTitleFont: UIFont {
        scaled(baseFont: .systemFont(ofSize: 17, weight: .light), forTextStyle: .headline)
    }
    static var descriptionFont: UIFont {
        scaled(baseFont: .systemFont(ofSize: 14, weight: .light), forTextStyle: .callout)
    }
    
    static var display1: UIFont {
        scaled(baseFont: .systemFont(ofSize: 42, weight: .semibold), forTextStyle: .largeTitle, maximumFactor: 1.5)
    }
    static var display2: UIFont {
        scaled(baseFont: .systemFont(ofSize: 36, weight: .semibold), forTextStyle: .largeTitle, maximumFactor: 1.5)
    }

    static var title1: UIFont {
        scaled(baseFont: .systemFont(ofSize: 24, weight: .semibold), forTextStyle: .title1)
    }

    static var title2: UIFont {
        scaled(baseFont: .systemFont(ofSize: 20, weight: .semibold), forTextStyle: .title2)
    }

    static var title3: UIFont {
        scaled(baseFont: .systemFont(ofSize: 18, weight: .semibold), forTextStyle: .title3)
    }

    static var title4: UIFont {
        scaled(baseFont: .systemFont(ofSize: 14, weight: .regular), forTextStyle: .headline)
    }

    static var title5: UIFont {
        scaled(baseFont: .systemFont(ofSize: 12, weight: .regular), forTextStyle: .subheadline)
    }

    static var bodyBold: UIFont {
        scaled(baseFont: .systemFont(ofSize: 16, weight: .semibold), forTextStyle: .body)
    }

    static var body: UIFont {
        scaled(baseFont: .systemFont(ofSize: 16, weight: .light), forTextStyle: .body)
    }

    static var captionBold: UIFont {
        scaled(baseFont: .systemFont(ofSize: 14, weight: .semibold), forTextStyle: .caption1)
    }

    static var caption: UIFont {
        scaled(baseFont: .systemFont(ofSize: 14, weight: .light), forTextStyle: .caption1)
    }

    static var small: UIFont {
        scaled(baseFont: .systemFont(ofSize: 12, weight: .light), forTextStyle: .footnote)
    }
}

public extension Wrapper where Base: UIFont {
    // Static properties to access each font family
    static var PingFangLight: FontFamily { .pingFangLight }
    static var PingFang: FontFamily { .pingFang }
    static var PingFangMedium: FontFamily { .pingFangMedium }
    static var PingFangSemiBold: FontFamily { .pingFangSemiBold }
    static var Alibaba: FontFamily { .alibaba }
    static var AlibabaThin: FontFamily { .alibabaThin }
    static var Sanji: FontFamily { .sanji }
    static var Digital: FontFamily { .digital }
    static var DigitalItalic: FontFamily { .digitalItalic }
    static var DinAlternateBold: FontFamily { .dinAlternateBold }
    static var SjChaoCuJiHeiRegular: FontFamily { .sjChaoCuJiHeiRegular }
    static var SjYiHeiRegular: FontFamily { .sjYiHeiRegular }
    static var Montserrat: FontFamily { .montserrat }
    
    enum FontFamily: String {
        case pingFangLight = "PingFangSC-Light"
        case pingFang = "PingFangSC-Regular"
        case pingFangMedium = "PingFangSC-Medium"
        case pingFangSemiBold = "PingFangSC-Semibold"
        case alibaba = "AlibabaPuHuiTi-Regular"
        case alibabaThin = "AlibabaPuHuiTi_3_35_Thin"
        case sanji = "SJhuolihei"
        case digital = "Digital-7 Mono"
        case digitalItalic = "Digital-7 Italic"
        case dinAlternateBold = "DIN Alternate Bold"
        case sjChaoCuJiHeiRegular = "SJchaocujihei"
        case sjYiHeiRegular = "SJyihei"
        case montserrat = "Montserrat-Medium"
        
        public func font(size: CGFloat = 16, weight: UIFont.Weight = .regular, textStyle: UIFont.TextStyle = .body, maxScaleFactor: CGFloat? = nil, isItalic: Bool = false) -> UIFont {
    
            let baseFont = UIFont(name: self.rawValue, size: size) ?? .systemFont(ofSize: size, weight: weight)
            var attrs: [UIFontDescriptor.AttributeName : Any] = [.traits: [UIFontDescriptor.TraitKey.weight: weight]]
            if isItalic {
                attrs[.symbolic] = UIFontDescriptor.SymbolicTraits.traitItalic
            }
            let fontDescriptor = baseFont.fontDescriptor.addingAttributes(attrs)
            let customFont = UIFont(descriptor: fontDescriptor, size: size)
            return scaled(baseFont: customFont, forTextStyle: textStyle, maximumFactor: maxScaleFactor)
        }
        
        public func font(_ size: CGFloat = 16) -> UIFont {
            let baseFont = UIFont(name: self.rawValue, size: size) ?? .systemFont(ofSize: size)
            return scaled(baseFont: baseFont, forTextStyle: .body)
        }
        
        public var title1: UIFont { return font(size: 24, textStyle: .title1) }
        public var title2: UIFont  { return font(size: 20, textStyle: .title2) }
        public var title3: UIFont  { return font(size: 18, textStyle: .title3) }
        public var body: UIFont { return font(size: 16, textStyle: .body) }
        public var caption: UIFont { return font(size: 14, textStyle: .footnote) }
        public var small: UIFont { return font(size: 12, textStyle: .footnote) }
    }
}

extension Wrapper where Base: UIFont {
    private static func scaled(baseFont: UIFont, forTextStyle textStyle: UIFont.TextStyle = .body, maximumFactor: CGFloat? = nil) -> UIFont {
        let fontMetrics = UIFontMetrics(forTextStyle: textStyle)
        
        if let maximumFactor = maximumFactor {
            let maximumPointSize = baseFont.pointSize * maximumFactor
            return fontMetrics.scaledFont(for: baseFont, maximumPointSize: maximumPointSize)
        }
        return fontMetrics.scaledFont(for: baseFont)
    }
}
